<?php

namespace common\widgets;

use Yii;
use yii\base\Widget;
use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;
use common\helpers\Html;

/**
 * ConsoleActions displays a list of items indicating the position of the current page in the whole site hierarchy.
 *
 * For example, breadcrumbs like "Home / Sample Post / Edit" means the user is viewing an edit page
 * for the "Sample Post". He can click on "Sample Post" to view that page, or he can click on "Home"
 * to return to the homepage.
 *
 * To use Breadcrumbs, you need to configure its [[items]] property, which specifies the items to be displayed. For example,
 *
 * ```php
 * // $this is the view object currently being used
 * echo Breadcrumbs::widget([
 *     'itemTemplate' => "<li><i>{item}</i></li>\n", // template for all items
 *     'items' => [
 *         [
 *             'label' => 'Post Category',
 *             'url' => ['post-category/view', 'id' => 10],
 *             'template' => "<li><b>{item}</b></li>\n", // template for this item only
 *         ],
 *         ['label' => 'Sample Post', 'url' => ['post/edit', 'id' => 1]],
 *         'Edit',
 *     ],
 * ]);
 * ```
 *
 * Because breadcrumbs usually appears in nearly every page of a website, you may consider placing it in a layout view.
 * You can use a view parameter (e.g. `$this->params['breadcrumbs']`) to configure the items in different
 * views. In the layout view, you assign this view parameter to the [[items]] property like the following:
 *
 * ```php
 * // $this is the view object currently being used
 * echo Breadcrumbs::widget([
 *     'items' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
 * ]);
 * ```
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
class ConsoleActions extends Widget {

    /**
     * @var string the name of the breadcrumb container tag.
     */
    public $tag = 'div';

    /**
     * @var array the HTML attributes for the breadcrumb container tag.
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
     */
    public $options = ['class' => 'console-actions'];

    /**
     * @var boolean whether to HTML-encode the item labels.
     */
    public $encodeLabels = false;

    /**
     * @var array the first hyperitem in the breadcrumbs (called home item).
     * Please refer to [[items]] on the format of the item.
     * If this property is not set, it will default to a item pointing to [[\yii\web\Application::homeUrl]]
     * with the label 'Home'. If this property is false, the home item will not be rendered.
     */
    public $itemCssClass = 'btn btn-sm default';

    /**
     * @var array list of items to appear in the breadcrumbs. If this property is empty,
     * the widget will not render anything. Each array element represents a single item in the breadcrumbs
     * with the following structure:
     *
     * ```php
     * [
     *     'label' => 'label of the item',  // required
     *     'url' => 'url of the item',      // optional, will be processed by Url::to()
     *     'template' => 'own template of the item', // optional, if not set $this->itemTemplate will be used
     * ]
     * ```
     *
     * If a item is active, you only need to specify its "label", and instead of writing `['label' => $label]`,
     * you may simply use `$label`.
     *
     * Since version 2.0.1, any additional array elements for each item will be treated as the HTML attributes
     * for the hyperitem tag. For example, the following item specification will generate a hyperitem
     * with CSS class `external`:
     *
     * ```php
     * [
     *     'label' => 'demo',
     *     'url' => 'http://example.com',
     *     'class' => 'external',
     * ]
     * ```
     *
     * Since version 2.0.3 each individual item can override global [[encodeLabels]] param like the following:
     *
     * ```php
     * [
     *     'label' => '<strong>Hello!</strong>',
     *     'encode' => false,
     * ]
     * ```
     *
     */
    public $items = [];
    public $pjax = false;

    /**
     * Renders the widget.
     */
    public function run() {
        if (empty($this->items)) {
            return;
        }
        $items = [];
        foreach ($this->items as $item) {
            if (!is_array($item)) {
                $item = ['label' => $item];
            }
            if (isset($item['renderForm'])) {
                $items[] = $item['renderForm'];
                continue;
            }
            $visible = ArrayHelper::remove($item, 'visible', true);
            if ($visible === false) {
                continue;
            }
            $items[] = $this->renderItem($item);
        }
        echo Html::tag($this->tag, implode("\n", $items), $this->options);
    }

    /**
     * Renders a single breadcrumb item.
     * @param array $item the item to be rendered. It must contain the "label" element. The "url" element is optional.
     * @param string $template the template to be used to rendered the item. The token "{item}" will be replaced by the item.
     * @return string the rendering result
     * @throws InvalidConfigException if `$item` does not have "label" element.
     */
    protected function renderItem($item) {
        $encodeLabel = ArrayHelper::remove($item, 'encode', $this->encodeLabels);
        if (array_key_exists('label', $item)) {
            $label = $encodeLabel ? Html::encode($item['label']) : $item['label'];
        } else {
            throw new InvalidConfigException('The "label" element is required for each item.');
        }

        $options = ArrayHelper::getValue($item, 'options', []);
        Html::addCssClass($options, $this->itemCssClass);
        if (!$this->pjax) {
            $options['data-pjax'] = 0;
        }
        if (isset($item['tag'])) {
            if ($item['tag'] == 'ajaxModal') {
                return Html::ajaxModal($label, isset($item['url']) ? $item['url'] : null, $options);
            } elseif ($item['tag'] == 'dropDownMenu') {
                $items = ArrayHelper::getValue($item, 'items', []);
                return Html::dropDownMenu($label, $items);
            }
        }
        return Html::a($label, isset($item['url']) ? $item['url'] : '#', $options);
    }

}
